package MF1DSolver;

import FEMShapeFunction1D.FEMShapeFunction1D1;
import Integration.GaussQuadrature;
import Integration.IFunction1D;
import MeshlessShapeFunctions.JMeshlessInterpolationFunction1D2;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author mark
 */
public class ElementMatrixGeneratorMF1D2 {
    protected JMeshlessInterpolationFunction1D2 phi1;
    protected JMeshlessInterpolationFunction1D2 phi2;
    protected GaussQuadrature gau;
    protected double a;
    protected double b;
    public double left =0;
    public double right=1;


    public ElementMatrixGeneratorMF1D2() {
        gau = new GaussQuadrature(100);////////////////////////////////////////////////
    }

    public ElementMatrixGeneratorMF1D2(JMeshlessInterpolationFunction1D2 phi1, JMeshlessInterpolationFunction1D2 phi2) {
        this.phi1 = phi1;
        this.phi2 = phi2;
        gau = new GaussQuadrature(100);////////////////////////////////////////////////
    }

    public JMeshlessInterpolationFunction1D2 getPhi1() {
        return phi1;
    }

    public void setPhi1(JMeshlessInterpolationFunction1D2 phi1) {
        this.phi1 = phi1;
    }

    public JMeshlessInterpolationFunction1D2 getPhi2() {
        return phi2;
    }

    public void setPhi2(JMeshlessInterpolationFunction1D2 phi2) {
        this.phi2 = phi2;
    }

    public void update(){
        a = Math.max(phi1.getXii()-phi1.getRho(), phi2.getXii()-phi2.getRho());
        a = Math.max(a, left);
        b = Math.min(phi1.getXii()+phi1.getRho(), phi2.getXii()+phi2.getRho());
        b = Math.min(right, b);
    }

    public double generateMeElement(final IFunction1D q){
        if(b>a){
            return gau.justGauss(a, b, new  IFunction1D() {

                public double calculate(double x) {
                    return phi1.calculate(x)*phi2.calculate(x)*q.calculate(x);
                }

                public double calculateDerivaty(double x) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });
        }
        return 0;
        
    }

    public double generateKeElement(final IFunction1D p){
        if(b>a){
            return gau.justGauss(a, b, new  IFunction1D() {
                public double calculate(double x) {
                    return phi1.calculateDiffuseDerivaty(x)*phi2.calculateDiffuseDerivaty(x)*p.calculate(x);
                    //return phi1.calculateDerivaty(x)*phi2.calculateDerivaty(x);
                }
                public double calculateDerivaty(double x) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });
        }
        return 0;
    }

    public double generatePeElement(final IFunction1D w){
        if(b<a){
            return 0;
        }
        return gau.justGauss(a, b, new  IFunction1D() {

            public double calculate(double x) {
                return phi2.calculate(x)*phi1.calculateDiffuseDerivaty(x)*w.calculate(x);
            }

            public double calculateDerivaty(double x) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        });
    }

    public double generateFeElement(final IFunction1D func){
        double tmpb = Math.min(right, phi1.getXii()+phi1.getRho());
        double tmpa = Math.max(phi1.getXii()-phi1.getRho(), left);
        return gau.justGauss(tmpa, tmpb, new  IFunction1D() {

            public double calculate(double x) {
                return func.calculate(x)*phi1.calculate(x);
            }

            public double calculateDerivaty(double x) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        });
    }

    public double generateLagrangeElement(final FEMShapeFunction1D1 q){
//        double tmpa = Math.max(left-q.getH(), Math.max(phi1.getXii()-phi1.getRho(), q.getXi()-q.getH()));
//        double tmpb = Math.min(right, Math.min(phi1.getXii()+phi1.getRho(), q.getXi()+q.getH()));
        double tmpa = Math.max(left, Math.max(phi1.getXii()-phi1.getRho(), q.getXi()-q.getH()));
        double tmpb = Math.min(right, Math.min(phi1.getXii()+phi1.getRho(), q.getXi()+q.getH()));
        if(tmpb>tmpa){
            //return gau.justGauss(tmpa, tmpb, new  IFunction1D() {
            return gau.justGauss(q.getXi(), q.getXi()+q.getH(), new  IFunction1D() {

                public double calculate(double x) {
                    return phi1.calculate(x)*q.calculate(x);
                }

                public double calculateDerivaty(double x) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });
        }
        return 0;

    }

}
